home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Files / MoreIsBetter / MIB-Libraries / Sources / MorePreferences.cp < prev    next >
Encoding:
Text File  |  1998-09-25  |  8.5 KB  |  391 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        MorePreferences.cp
  3.  
  4.     Contains:    
  5.  
  6.     Written by:    Pete Gontier (PCG)
  7.  
  8.     Copyright:    Copyright (c) 1998 Apple Computer, Inc.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <2>     7/24/98    PCG        UPP's for collection un/flattening
  13.          <1>     6/16/98    PCG     initial checkin
  14. */
  15.  
  16.  
  17. #define OLDROUTINELOCATIONS        0
  18. #define OLDROUTINENAMES            0
  19. #define SystemSevenOrLater        1
  20.  
  21. #ifndef __SCRIPT__
  22. #    include <Script.h>
  23. #endif
  24.  
  25. #ifndef __COLLECTIONS__
  26. #    include <Collections.h>
  27. #endif
  28.  
  29. #ifndef __FOLDERS__
  30. #    include <Folders.h>
  31. #endif
  32.  
  33. #ifndef __ERRORS__
  34. #    include <Errors.h>
  35. #endif
  36.  
  37. #include "MorePreferences.h"
  38. #include "MoreProcesses.h"
  39. #include "MoreCRC.h"
  40.  
  41. enum
  42. {
  43.     kPrefsFileMagicCookie    = 'ferp'
  44. };
  45.  
  46. typedef struct
  47. {
  48.     UInt32            crc;
  49.     UInt32            cookies [2];
  50.     UInt8            flatCollectionData [ ];
  51. }
  52. tPrefsFormat, *tPrefsFormatP, **tPrefsFormatH;
  53.  
  54. typedef struct
  55. {
  56.     short            fileRefNum;
  57.     tPrefsFormatP    prefsHeader;
  58. }
  59. tCollectionFlattenState, *tCollectionFlattenStateP;
  60.  
  61. typedef struct
  62. {
  63.     tPrefsFormatH    prefsData;
  64.     UInt32            offset;
  65. }
  66. tCollectionUnflattenState, *tCollectionUnflattenStateP;
  67.  
  68. ////////////////////////////////////////////////////////////////////////////////////////////////////
  69.  
  70. pascal OSErr NewPrefsCollection (PrefsCollection *newPrefs)
  71. {
  72.     *newPrefs = PrefsCollection (NewCollection ( ));
  73.     if (!*newPrefs) return nilHandleErr;
  74.     return noErr;
  75. }
  76.  
  77. pascal OSErr DisposePrefsCollection (PrefsCollection doomedPrefs)
  78. {
  79.     DisposeCollection (Collection (doomedPrefs));
  80.     return noErr;
  81. }
  82.  
  83. ////////////////////////////////////////////////////////////////////////////////////////////////////
  84.  
  85. static pascal OSErr NewFSSpec (short vRefNum, long parID, ConstStr255Param path, FSSpecPtr *fssPP)
  86. {
  87.     OSErr err = noErr;
  88.  
  89.     if (!(*fssPP = FSSpecPtr (NewPtr (sizeof (**fssPP)))))
  90.         err = MemError ( );
  91.     else
  92.     {
  93.         err = FSMakeFSSpec (vRefNum,parID,path,*fssPP);
  94.  
  95.         if (err && err != fnfErr)
  96.         {
  97.             DisposePtr (Ptr (*fssPP));
  98.             *fssPP = nil;
  99.         }
  100.     }
  101.  
  102.     return err;    
  103. }
  104.  
  105. static pascal OSErr NewHParamBlock (HParmBlkPtr &hpbp)
  106. {
  107.     hpbp = HParmBlkPtr (NewPtrClear (sizeof (*hpbp)));
  108.     if (!hpbp) return MemError ( );
  109.     return noErr;
  110. }
  111.  
  112. static pascal OSErr ScanDirectory
  113.     (short vRefNum, long dirID, Str31 firstNameFound, OSType fdCreator, UInt16 &count)
  114. {
  115.     OSErr err = noErr;
  116.  
  117.     HParmBlkPtr hpbp;
  118.  
  119.     if (!(err = NewHParamBlock (hpbp)))
  120.     {
  121.         hpbp->fileParam.ioFDirIndex        = 1;
  122.         hpbp->fileParam.ioVRefNum        = vRefNum;
  123.         hpbp->fileParam.ioDirID            = dirID;
  124.         hpbp->fileParam.ioNamePtr        = firstNameFound;
  125.  
  126.         count = 0;
  127.  
  128.         while (!(err = PBHGetFInfoSync (hpbp)))
  129.         {
  130.             if (kPrefsFileType == hpbp->fileParam.ioFlFndrInfo.fdType)
  131.             if (fdCreator == hpbp->fileParam.ioFlFndrInfo.fdCreator)
  132.             {
  133.                 hpbp->fileParam.ioNamePtr = nil;
  134.                 ++count;
  135.             }
  136.  
  137.             hpbp->fileParam.ioFDirIndex        += 1;
  138.             hpbp->fileParam.ioDirID            = dirID;
  139.         }
  140.  
  141.         if (err == fnfErr)
  142.             err = noErr;
  143.  
  144.         DisposePtr (Ptr (hpbp));
  145.         if (!err) err = MemError ( );
  146.     }
  147.  
  148.     return err;
  149. }
  150.  
  151. static pascal OSErr GetPrefsSpec (ConstStr255Param fileName, OSType processSignature, FSSpecPtr &fssP, UInt16 &count)
  152. {
  153.     OSErr    err = noErr;
  154.     short    vRefNum;
  155.     long    dirID;
  156.  
  157.     if (!(err = FindFolder (kOnSystemDisk,kPreferencesFolderType,kDontCreateFolder,&vRefNum,&dirID)))
  158.     {
  159.         Str31 firstNameFound;
  160.  
  161.         if (!(err = ScanDirectory (vRefNum,dirID,firstNameFound,processSignature,count)))
  162.         {
  163.             if (!count)
  164.                 err = NewFSSpec (vRefNum,dirID,fileName,&fssP);
  165.             else if (count == 1)
  166.                 err = NewFSSpec (vRefNum,dirID,firstNameFound,&fssP);
  167.             else if (fileName)
  168.                 err = NewFSSpec (vRefNum,dirID,fileName,&fssP);
  169.             else
  170.                 err = fnfErr;
  171.         }
  172.     }
  173.  
  174.     return err;
  175. }
  176.  
  177. pascal OSErr GetNewPrefsCollection (PrefsCollection *newPrefs, ConstStr255Param fileName)
  178. {
  179.     OSErr err = noErr;
  180.  
  181.     ProcessInfoRec pir;
  182.  
  183.     if (!(err = GetSomeProcessInfo (nil,&pir)))
  184.     {
  185.         FSSpecPtr    fssP;
  186.         UInt16        count;
  187.  
  188.         err = GetPrefsSpec (fileName,pir.processSignature,fssP,count);
  189.  
  190.         if (!err)
  191.             err = GetNewPrefsCollectionFromFile (newPrefs,fssP);
  192.  
  193.         if (fssP)
  194.         {
  195.             DisposePtr (Ptr (fssP));
  196.             if (!err) err = MemError ( );
  197.         }
  198.     }
  199.  
  200.     return err;
  201. }
  202.  
  203. pascal OSErr WritePrefsCollection (PrefsCollection pc, ConstStr255Param fileName)
  204. {
  205.     OSErr err = noErr;
  206.  
  207.     ProcessInfoRec pir;
  208.  
  209.     if (!(err = GetSomeProcessInfo (nil,&pir)))
  210.     {
  211.         FSSpecPtr    fssP;
  212.         UInt16        count;
  213.         Boolean        createdItHere = false;
  214.  
  215.         err = GetPrefsSpec (fileName,pir.processSignature,fssP,count);
  216.  
  217.         if (err == fnfErr && !count)
  218.         {
  219.             err = FSpCreate (fssP,pir.processSignature,kPrefsFileType,smSystemScript);
  220.             if (!err) createdItHere = true;
  221.         }
  222.  
  223.         if (!err)
  224.         {
  225.             err = WritePrefsCollectionToFile (pc,fssP);
  226.             if (err && createdItHere) (void) FSpDelete (fssP);
  227.         }
  228.  
  229.         if (fssP)
  230.         {
  231.             DisposePtr (Ptr (fssP));
  232.             if (!err) err = MemError ( );
  233.         }
  234.     }
  235.  
  236.     return err;
  237. }
  238.  
  239. static pascal OSErr CollectionUnflattenProc (SInt32 size, void *data, void *refCon)
  240. {
  241.     tCollectionUnflattenStateP state = tCollectionUnflattenStateP (refCon);
  242.     BlockMove (state->offset + (**(state->prefsData)).flatCollectionData, data, size);
  243.     state->offset += size;
  244.     return noErr;
  245. }
  246.  
  247. pascal OSErr GetNewPrefsCollectionFromFile (PrefsCollection *pc, const FSSpec *fssP)
  248. {
  249.     OSErr err = noErr;
  250.  
  251.     short fileRefNum;
  252.  
  253.     if (!(err = FSpOpenDF (fssP,fsRdPerm,&fileRefNum)))
  254.     {
  255.         Size eof;
  256.  
  257.         if (!(err = GetEOF (fileRefNum, &eof)))
  258.         {
  259.             Handle crcBuffer = NewHandle (eof);
  260.  
  261.             if (!crcBuffer)
  262.                 err = MemError ( );
  263.             else
  264.             {
  265.                 HLockHi (crcBuffer);
  266.                 if (!(err = MemError ( )))
  267.                 {
  268.                     if (!(err = FSRead (fileRefNum,&eof,*crcBuffer)))
  269.                     {
  270.                         tPrefsFormatH flatPrefs = tPrefsFormatH (crcBuffer);
  271.  
  272.                         if ((**flatPrefs).cookies [0] != kPrefsFileMagicCookie)
  273.                             err = badFileFormat;
  274.                         else if ((**flatPrefs).cookies [1] != kPrefsFileMagicCookie)
  275.                             err = badFileFormat;
  276.                         else
  277.                         {
  278.                             UInt32 crc = MoreCRC32 (0, (**flatPrefs).flatCollectionData, eof - sizeof (tPrefsFormat));
  279.  
  280.                             if ((**flatPrefs).crc != crc)
  281.                                 err = badFileFormat;
  282.                             else if (!(err = NewPrefsCollection (pc)))
  283.                             {
  284.                                 HUnlock (crcBuffer);
  285.                                 if (!(err = MemError ( )))
  286.                                 {
  287.                                     CollectionFlattenUPP upp = NewCollectionFlattenProc (CollectionUnflattenProc);
  288.  
  289.                                     if (!upp)
  290.                                         err = MemError ( );
  291.                                     else
  292.                                     {
  293.                                         tCollectionUnflattenState unflattenState = { flatPrefs, 0 };
  294.                                         err = UnflattenCollection (Collection (*pc),upp,&unflattenState);
  295.                                         DisposeRoutineDescriptor (upp);
  296.                                     }
  297.                                 }
  298.  
  299.                                 if (err) DisposePrefsCollection (*pc);
  300.                             }
  301.                         }                        
  302.                     }
  303.                 }
  304.  
  305.                 DisposeHandle (crcBuffer);
  306.                 if (!err) err = MemError ( );
  307.             }
  308.         }
  309.  
  310.         OSErr err2 = FSClose (fileRefNum);
  311.         if (!err) err = err2;
  312.     }
  313.  
  314.     return err;
  315. }
  316.  
  317. static pascal OSErr CollectionFlattenProc (SInt32 size, void *data, void *refCon)
  318. {
  319.     tCollectionFlattenStateP state = tCollectionFlattenStateP (refCon);
  320.     state->prefsHeader->crc = MoreCRC32 (state->prefsHeader->crc, data, size);
  321.     return FSWrite (state->fileRefNum, &size, data);
  322. }
  323.  
  324. pascal OSErr WritePrefsCollectionToFile (PrefsCollection pc, const FSSpec *fssP)
  325. {
  326.     OSErr err = noErr;
  327.  
  328.     short fileRefNum;
  329.  
  330.     if (!(err = FSpOpenDF (fssP,fsWrPerm,&fileRefNum)))
  331.     {
  332.         if (!(err = SetEOF (fileRefNum, sizeof (tPrefsFormat))))
  333.         if (!(err = SetFPos (fileRefNum, fsFromStart, sizeof (tPrefsFormat))))
  334.         {
  335.             CollectionFlattenUPP upp = NewCollectionFlattenProc (CollectionFlattenProc);
  336.  
  337.             if (!upp)
  338.                 err = MemError ( );
  339.             else
  340.             {
  341.                 tPrefsFormat                header    = { 0, kPrefsFileMagicCookie, kPrefsFileMagicCookie };
  342.                 tCollectionFlattenState        state    = { fileRefNum, &header };
  343.  
  344.                 if (!(err = FlattenCollection (Collection (pc), upp, &state)))
  345.                 {
  346.                     if (!(err = SetFPos (fileRefNum, fsFromStart, 0)))
  347.                     {
  348.                         Size writeSize = sizeof (header);
  349.                         err = FSWrite (fileRefNum,&writeSize,&header);
  350.                     }
  351.                 }
  352.  
  353.                 DisposeRoutineDescriptor (upp);
  354.             }
  355.         }
  356.  
  357.         OSErr err2 = FSClose (fileRefNum);
  358.         if (!err) err = err2;
  359.         err2 = FlushVol (nil, fssP->vRefNum);
  360.         if (!err) err = err2;
  361.     }
  362.  
  363.     return err;
  364. }
  365.  
  366. pascal OSErr SetPreference (PrefsCollection pc, PrefsType pt, PrefsID pid, Size ps, void *pb)
  367. {
  368.     if (!MoreAssert (kPrefsReservedType != pt)) return paramErr;
  369.  
  370.     OSErr err = RemoveCollectionItem (Collection (pc), pt, pid);
  371.  
  372.     if (!err || err == collectionItemNotFoundErr)
  373.         err = AddCollectionItem (Collection (pc), pt, pid, ps, pb);
  374.  
  375.     return err;
  376. }
  377.  
  378. pascal OSErr GetPreference (PrefsCollection pc, PrefsType pt, PrefsID pid, Size ps, Size *aps, void *pb)
  379. {
  380.     if (!MoreAssert (kPrefsReservedType != pt)) return paramErr;
  381.     if (aps) *aps = ps; else aps = &ps;
  382.     return GetCollectionItem (Collection (pc), pt, pid, aps, pb);
  383. }
  384.  
  385. pascal OSErr PrefsAreSame (PrefsCollection,PrefsCollection, Boolean *areSame)
  386. {
  387.     DebugStr ("\pno comparison performed -- returning false");
  388.     *areSame = false;
  389.     return noErr;
  390. }
  391.